Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Node / ReticulumProjects / MeshChatX.git / files / tests / backend / test_interface_discovery_ifac.py

Displaying Raw • Download


tests/backend/test_interface_discovery_ifac.py v4.7.0-rc.4 (448cd46c) Text, 11.39 KB

T8b949e# SPDX-License-Identifier: 0BSD
T8b949e"""Tests for encrypted IFAC values surfaced via interface discovery announces.

When an upstream interface is configured with publish_ifac = yes, RNS embeds
the network_name (ifac_netname) and passphrase (ifac_netkey) into the
discovery announce payload, plus a ready-to-paste config_entry block. These
tests verify that:

1. The /api/v1/reticulum/discovered-interfaces endpoint passes those fields
through to the frontend with both the raw RNS keys and the canonical
config-style aliases (network_name/passphrase).
2. ReticulumMeshChat.normalize_discovered_ifac_fields handles bytes payloads,
missing values, and non-list inputs without raising.
3. discovery_filter_candidates includes network_name so users can whitelist
or blacklist by IFAC network name.
"""

Tff7b72import T7ee787json
Tff7b72import T7ee787shutil
Tff7b72import T7ee787tempfile
Tff7b72from T7ee787unittestT7ee787.T7ee787mock Tff7b72import Te6edf3MagicMockTb4b4b4, Te6edf3patch

Tff7b72import T7ee787pytest
Tff7b72import T7ee787RNS

Tff7b72from T7ee787meshchatxT7ee787.T7ee787meshchat Tff7b72import Te6edf3ReticulumMeshChat


Tff7b72class T56d364ConfigDictTb4b4b4(Tffa657dictTb4b4b4)Tb4b4b4:
Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Tff7b72*Te6edf3argsTb4b4b4, Tff7b72*Tff7b72*Te6edf3kwargsTb4b4b4)Tb4b4b4:
Tffa657superTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ff__init__Tb4b4b4(Tff7b72*Te6edf3argsTb4b4b4, Tff7b72*Tff7b72*Te6edf3kwargsTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffwrite_called Tff7b72= Tff7b72False

Tff7b72def Td2a8ffwriteTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffwrite_called Tff7b72= Tff7b72True
Tff7b72return Tff7b72True


Tf0883e@pytestTff7b72.Td2a8fffixture
Tff7b72def Td2a8fftemp_dirTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3path Tff7b72= Te6edf3tempfileTff7b72.Td2a8ffmkdtempTb4b4b4(Tb4b4b4)
Tff7b72tryTb4b4b4:
Tff7b72yield Te6edf3path
Tff7b72finallyTb4b4b4:
Te6edf3shutilTff7b72.Td2a8ffrmtreeTb4b4b4(Te6edf3pathTb4b4b4)


Tff7b72def Td2a8ffbuild_identityTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3identity Tff7b72= Te6edf3MagicMockTb4b4b4(Te6edf3specTff7b72=Te6edf3RNSTff7b72.Td2a8ffIdentityTb4b4b4)
Te6edf3identityTff7b72.Td2a8ffhash Tff7b72= Ta5d6ffbTa5d6ff"Ta5d6fftest_hash_32_bytes_long_01234567Ta5d6ff"
Te6edf3identityTff7b72.Td2a8ffhexhash Tff7b72= Te6edf3identityTff7b72.Td2a8ffhashTff7b72.Td2a8ffhexTb4b4b4(Tb4b4b4)
Te6edf3identityTff7b72.Td2a8ffget_private_keyTff7b72.Td2a8ffreturn_value Tff7b72= Ta5d6ffbTa5d6ff"Ta5d6fftest_private_keyTa5d6ff"
Tff7b72return Te6edf3identity


Tff7b72async Tff7b72def Td2a8fffind_route_handlerTb4b4b4(Te6edf3app_instanceTb4b4b4, Te6edf3pathTb4b4b4, Te6edf3methodTb4b4b4)Tb4b4b4:
Tff7b72for Te6edf3route Tff7b72in Te6edf3app_instanceTff7b72.Td2a8ffget_routesTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3routeTff7b72.Td2a8ffpath Tff7b72== Te6edf3path Tff7b72and Te6edf3routeTff7b72.Td2a8ffmethod Tff7b72== Te6edf3methodTb4b4b4:
Tff7b72return Te6edf3routeTff7b72.Td2a8ffhandler
Tff7b72return Tff7b72None


Tff7b72def Td2a8fftest_normalize_handles_non_list_inputTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72assert Te6edf3ReticulumMeshChatTff7b72.Td2a8ffnormalize_discovered_ifac_fieldsTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6fffooTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffbarTa5d6ff"Tb4b4b4}Tb4b4b4) Tff7b72== Tb4b4b4{
Ta5d6ff"Ta5d6fffooTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffbarTa5d6ff"
Tb4b4b4}
Tff7b72assert Te6edf3ReticulumMeshChatTff7b72.Td2a8ffnormalize_discovered_ifac_fieldsTb4b4b4(Tff7b72NoneTb4b4b4) Tff7b72is Tff7b72None


Tff7b72def Td2a8fftest_normalize_aliases_string_ifac_fieldsTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3interfaces Tff7b72= Tb4b4b4[
Tb4b4b4{
Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffkin.earthTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6fftypeTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffBackboneInterfaceTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffreachable_onTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffrns.kin.earthTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffportTa5d6ff"Tb4b4b4: T79c0ff4242Tb4b4b4,
Ta5d6ff"Ta5d6ffifac_netnameTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffkin.earthTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffifac_netkeyTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffasty8vT8spXNQdCnPVMATbCKkwUxuzG9Ta5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffconfig_entryTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ff[[kin.earth]]Tffea00\nTa5d6ff type = BackboneInterfaceTffea00\nTa5d6ff enabled = yesTa5d6ff"Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4]

Te6edf3normalized Tff7b72= Te6edf3ReticulumMeshChatTff7b72.Td2a8ffnormalize_discovered_ifac_fieldsTb4b4b4(Te6edf3interfacesTb4b4b4)

Tff7b72assert Te6edf3normalizedTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffifac_netnameTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffkin.earthTa5d6ff"
Tff7b72assert Te6edf3normalizedTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffifac_netkeyTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffasty8vT8spXNQdCnPVMATbCKkwUxuzG9Ta5d6ff"
Tff7b72assert Te6edf3normalizedTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffnetwork_nameTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffkin.earthTa5d6ff"
Tff7b72assert Te6edf3normalizedTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffpassphraseTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffasty8vT8spXNQdCnPVMATbCKkwUxuzG9Ta5d6ff"
Tff7b72assert Te6edf3normalizedTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffpublish_ifacTa5d6ff"Tb4b4b4] Tff7b72is Tff7b72True
Tff7b72assert Te6edf3normalizedTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffconfig_entryTa5d6ff"Tb4b4b4]Tff7b72.Td2a8ffstartswithTb4b4b4(Ta5d6ff"Ta5d6ff[[kin.earth]]Ta5d6ff"Tb4b4b4)


Tff7b72def Td2a8fftest_normalize_decodes_bytes_ifac_fieldsTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3interfaces Tff7b72= Tb4b4b4[
Tb4b4b4{
Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffbytes-ifaceTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6fftypeTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffBackboneInterfaceTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffifac_netnameTa5d6ff"Tb4b4b4: Ta5d6ffbTa5d6ff"Ta5d6ffbytes_netTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffifac_netkeyTa5d6ff"Tb4b4b4: Ta5d6ffbTa5d6ff"Ta5d6ffbytes_keyTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffconfig_entryTa5d6ff"Tb4b4b4: Ta5d6ffbTa5d6ff"Ta5d6ff[[bytes-iface]]Tffea00\nTa5d6ff type = BackboneInterfaceTa5d6ff"Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4]
Te6edf3normalized Tff7b72= Te6edf3ReticulumMeshChatTff7b72.Td2a8ffnormalize_discovered_ifac_fieldsTb4b4b4(Te6edf3interfacesTb4b4b4)
Tff7b72assert Te6edf3normalizedTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffnetwork_nameTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffbytes_netTa5d6ff"
Tff7b72assert Te6edf3normalizedTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffpassphraseTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffbytes_keyTa5d6ff"
Tff7b72assert Te6edf3normalizedTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffconfig_entryTa5d6ff"Tb4b4b4]Tff7b72.Td2a8ffstartswithTb4b4b4(Ta5d6ff"Ta5d6ff[[bytes-iface]]Ta5d6ff"Tb4b4b4)


Tff7b72def Td2a8fftest_normalize_missing_ifac_fields_yields_none_aliasesTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3interfaces Tff7b72= Tb4b4b4[
Tb4b4b4{
Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffopen-ifaceTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6fftypeTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffTCPClientInterfaceTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffreachable_onTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ff10.0.0.1Ta5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffportTa5d6ff"Tb4b4b4: T79c0ff4242Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4]
Te6edf3normalized Tff7b72= Te6edf3ReticulumMeshChatTff7b72.Td2a8ffnormalize_discovered_ifac_fieldsTb4b4b4(Te6edf3interfacesTb4b4b4)
Tff7b72assert Te6edf3normalizedTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffifac_netnameTa5d6ff"Tb4b4b4] Tff7b72is Tff7b72None
Tff7b72assert Te6edf3normalizedTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffifac_netkeyTa5d6ff"Tb4b4b4] Tff7b72is Tff7b72None
Tff7b72assert Te6edf3normalizedTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffnetwork_nameTa5d6ff"Tb4b4b4] Tff7b72is Tff7b72None
Tff7b72assert Te6edf3normalizedTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffpassphraseTa5d6ff"Tb4b4b4] Tff7b72is Tff7b72None
Tff7b72assert Te6edf3normalizedTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffpublish_ifacTa5d6ff"Tb4b4b4] Tff7b72is Tff7b72False
Tff7b72assert Te6edf3normalizedTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffconfig_entryTa5d6ff"Tb4b4b4] Tff7b72is Tff7b72None


Tff7b72def Td2a8fftest_normalize_skips_non_dict_entriesTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3interfaces Tff7b72= Tb4b4b4[
Ta5d6ff"Ta5d6ffnot a dictTa5d6ff"Tb4b4b4,
Tb4b4b4{Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffokTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffifac_netnameTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffnTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffifac_netkeyTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffkTa5d6ff"Tb4b4b4}Tb4b4b4,
Tb4b4b4]
Te6edf3normalized Tff7b72= Te6edf3ReticulumMeshChatTff7b72.Td2a8ffnormalize_discovered_ifac_fieldsTb4b4b4(Te6edf3interfacesTb4b4b4)
Tff7b72assert Te6edf3normalizedTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffnot a dictTa5d6ff"
Tff7b72assert Te6edf3normalizedTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffnetwork_nameTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffnTa5d6ff"
Tff7b72assert Te6edf3normalizedTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffpassphraseTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffkTa5d6ff"


Tff7b72def Td2a8fftest_discovery_filter_candidates_includes_network_nameTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3iface Tff7b72= Tb4b4b4{
Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffnode-1Ta5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6fftypeTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffBackboneInterfaceTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffnetwork_nameTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffkin.earthTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffifac_netnameTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffkin.earthTa5d6ff"Tb4b4b4,
Tb4b4b4}
Te6edf3candidates Tff7b72= Te6edf3ReticulumMeshChatTff7b72.Td2a8ffdiscovery_filter_candidatesTb4b4b4(Te6edf3ifaceTb4b4b4)
Tff7b72assert Ta5d6ff"Ta5d6ffkin.earthTa5d6ff" Tff7b72in Te6edf3candidates


Tff7b72def Td2a8fftest_filter_discovered_interfaces_whitelist_by_network_nameTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3interfaces Tff7b72= Tb4b4b4[
Tb4b4b4{Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffgoodTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6fftypeTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffBackboneInterfaceTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffnetwork_nameTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffkin.earthTa5d6ff"Tb4b4b4}Tb4b4b4,
Tb4b4b4{Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffbadTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6fftypeTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffBackboneInterfaceTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffnetwork_nameTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffother.netTa5d6ff"Tb4b4b4}Tb4b4b4,
Tb4b4b4]
Te6edf3filtered Tff7b72= Te6edf3ReticulumMeshChatTff7b72.Td2a8fffilter_discovered_interfacesTb4b4b4(
Te6edf3interfacesTb4b4b4,
Te6edf3whitelist_patternsTff7b72=Ta5d6ff"Ta5d6ffkin.earthTa5d6ff"Tb4b4b4,
Te6edf3blacklist_patternsTff7b72=Ta5d6ff"Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Te6edf3names Tff7b72= Tb4b4b4[Te6edf3iTb4b4b4[Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4] Tff7b72for Te6edf3i Tff7b72in Te6edf3filteredTb4b4b4]
Tff7b72assert Te6edf3names Tff7b72== Tb4b4b4[Ta5d6ff"Ta5d6ffgoodTa5d6ff"Tb4b4b4]


Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffasyncio
Tff7b72async Tff7b72def Td2a8fftest_discovered_interfaces_endpoint_surfaces_ifacTb4b4b4(Te6edf3temp_dirTb4b4b4)Tb4b4b4:
T8b949e"""End-to-end: HTTP endpoint exposes IFAC values from RNS announce."""
Te6edf3config Tff7b72= Te6edf3ConfigDictTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffreticulumTa5d6ff"Tb4b4b4: Tb4b4b4{Tb4b4b4}Tb4b4b4, Ta5d6ff"Ta5d6ffinterfacesTa5d6ff"Tb4b4b4: Tb4b4b4{Tb4b4b4}Tb4b4b4}Tb4b4b4)

Tff7b72with Tb4b4b4(
Te6edf3patchTb4b4b4(Ta5d6ff"Ta5d6ffmeshchatx.meshchat.generate_ssl_certificateTa5d6ff"Tb4b4b4)Tb4b4b4,
Te6edf3patchTb4b4b4(Ta5d6ff"Ta5d6ffRNS.ReticulumTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3mock_rnsTb4b4b4,
Te6edf3patchTb4b4b4(Ta5d6ff"Ta5d6ffRNS.TransportTa5d6ff"Tb4b4b4)Tb4b4b4,
Te6edf3patchTb4b4b4(Ta5d6ff"Ta5d6ffLXMF.LXMRouterTa5d6ff"Tb4b4b4)Tb4b4b4,
Te6edf3patchTb4b4b4(Ta5d6ff"Ta5d6ffmeshchatx.meshchat.InterfaceDiscoveryTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3mock_discovery_clsTb4b4b4,
Tb4b4b4)Tb4b4b4:
Te6edf3mock_reticulum Tff7b72= Te6edf3mock_rnsTff7b72.Td2a8ffreturn_value
Te6edf3mock_reticulumTff7b72.Td2a8ffconfig Tff7b72= Te6edf3config
Te6edf3mock_reticulumTff7b72.Td2a8ffconfigpath Tff7b72= Ta5d6ff"Ta5d6ff/tmp/mock_configTa5d6ff"
Te6edf3mock_reticulumTff7b72.Td2a8ffis_connected_to_shared_instance Tff7b72= Tff7b72False
Te6edf3mock_reticulumTff7b72.Td2a8fftransport_enabledTff7b72.Td2a8ffreturn_value Tff7b72= Tff7b72True
Te6edf3mock_reticulumTff7b72.Td2a8ffget_interface_statsTff7b72.Td2a8ffreturn_value Tff7b72= Tb4b4b4{Ta5d6ff"Ta5d6ffinterfacesTa5d6ff"Tb4b4b4: Tb4b4b4[Tb4b4b4]Tb4b4b4}

Te6edf3cfg_block Tff7b72= Tb4b4b4(
Ta5d6ff"Ta5d6ff[[kin.earth]]Tffea00\nTa5d6ff"
Ta5d6ff"Ta5d6ff type = BackboneInterfaceTffea00\nTa5d6ff"
Ta5d6ff"Ta5d6ff enabled = yesTffea00\nTa5d6ff"
Ta5d6ff"Ta5d6ff remote = rns.kin.earthTffea00\nTa5d6ff"
Ta5d6ff"Ta5d6ff target_port = 4242Tffea00\nTa5d6ff"
Ta5d6ff"Ta5d6ff transport_identity = eea3d09f02143e157b3dae83060ee843Tffea00\nTa5d6ff"
Ta5d6ff"Ta5d6ff network_name = kin.earthTffea00\nTa5d6ff"
Ta5d6ff"Ta5d6ff passphrase = asty8vT8spXNQdCnPVMATbCKkwUxuzG9Ta5d6ff"
Tb4b4b4)

Te6edf3mock_discovery_clsTff7b72.Td2a8ffreturn_valueTff7b72.Td2a8fflist_discovered_interfacesTff7b72.Td2a8ffreturn_value Tff7b72= Tb4b4b4[
Tb4b4b4{
Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffkin.earthTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6fftypeTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffBackboneInterfaceTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffreachable_onTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffrns.kin.earthTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffportTa5d6ff"Tb4b4b4: T79c0ff4242Tb4b4b4,
Ta5d6ff"Ta5d6fftransport_idTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffeea3d09f02143e157b3dae83060ee843Ta5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffnetwork_idTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffabc123Ta5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffvalueTa5d6ff"Tb4b4b4: T79c0ff16Tb4b4b4,
Ta5d6ff"Ta5d6ffhopsTa5d6ff"Tb4b4b4: T79c0ff1Tb4b4b4,
Ta5d6ff"Ta5d6ffstatusTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffavailableTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6fflast_heardTa5d6ff"Tb4b4b4: T79c0ff1700000000Tb4b4b4,
Ta5d6ff"Ta5d6ffifac_netnameTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffkin.earthTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffifac_netkeyTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffasty8vT8spXNQdCnPVMATbCKkwUxuzG9Ta5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffconfig_entryTa5d6ff"Tb4b4b4: Te6edf3cfg_blockTb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4{
Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffopen-nodeTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6fftypeTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffBackboneInterfaceTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffreachable_onTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffopen.exampleTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffportTa5d6ff"Tb4b4b4: T79c0ff4242Tb4b4b4,
Ta5d6ff"Ta5d6fftransport_idTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffffTa5d6ff" Tff7b72* T79c0ff16Tb4b4b4,
Ta5d6ff"Ta5d6ffnetwork_idTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffdef456Ta5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffvalueTa5d6ff"Tb4b4b4: T79c0ff8Tb4b4b4,
Ta5d6ff"Ta5d6ffhopsTa5d6ff"Tb4b4b4: T79c0ff2Tb4b4b4,
Ta5d6ff"Ta5d6ffstatusTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffavailableTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6fflast_heardTa5d6ff"Tb4b4b4: T79c0ff1700000001Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4]

Te6edf3app_instance Tff7b72= Te6edf3ReticulumMeshChatTb4b4b4(
Te6edf3identityTff7b72=Te6edf3build_identityTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3storage_dirTff7b72=Te6edf3temp_dirTb4b4b4,
Te6edf3reticulum_config_dirTff7b72=Te6edf3temp_dirTb4b4b4,
Tb4b4b4)

Te6edf3handler Tff7b72= Tff7b72await Te6edf3find_route_handlerTb4b4b4(
Te6edf3app_instanceTb4b4b4,
Ta5d6ff"Ta5d6ff/api/v1/reticulum/discovered-interfacesTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffGETTa5d6ff"Tb4b4b4,
Tb4b4b4)
Tff7b72assert Te6edf3handler

Te6edf3response Tff7b72= Tff7b72await Te6edf3handlerTb4b4b4(Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3data Tff7b72= Te6edf3jsonTff7b72.Td2a8ffloadsTb4b4b4(Te6edf3responseTff7b72.Td2a8ffbodyTb4b4b4)
Te6edf3ifaces Tff7b72= Te6edf3dataTb4b4b4[Ta5d6ff"Ta5d6ffinterfacesTa5d6ff"Tb4b4b4]
Tff7b72assert Tffa657lenTb4b4b4(Te6edf3ifacesTb4b4b4) Tff7b72== T79c0ff2

Te6edf3encrypted Tff7b72= Tffa657nextTb4b4b4(Te6edf3i Tff7b72for Te6edf3i Tff7b72in Te6edf3ifaces Tff7b72if Te6edf3iTb4b4b4[Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffkin.earthTa5d6ff"Tb4b4b4)
Tff7b72assert Te6edf3encryptedTb4b4b4[Ta5d6ff"Ta5d6ffifac_netnameTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffkin.earthTa5d6ff"
Tff7b72assert Te6edf3encryptedTb4b4b4[Ta5d6ff"Ta5d6ffifac_netkeyTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffasty8vT8spXNQdCnPVMATbCKkwUxuzG9Ta5d6ff"
Tff7b72assert Te6edf3encryptedTb4b4b4[Ta5d6ff"Ta5d6ffnetwork_nameTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffkin.earthTa5d6ff"
Tff7b72assert Te6edf3encryptedTb4b4b4[Ta5d6ff"Ta5d6ffpassphraseTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffasty8vT8spXNQdCnPVMATbCKkwUxuzG9Ta5d6ff"
Tff7b72assert Te6edf3encryptedTb4b4b4[Ta5d6ff"Ta5d6ffpublish_ifacTa5d6ff"Tb4b4b4] Tff7b72is Tff7b72True
Tff7b72assert Te6edf3encryptedTb4b4b4[Ta5d6ff"Ta5d6ffconfig_entryTa5d6ff"Tb4b4b4]Tff7b72.Td2a8ffstartswithTb4b4b4(Ta5d6ff"Ta5d6ff[[kin.earth]]Ta5d6ff"Tb4b4b4)
Tff7b72assert Ta5d6ff"Ta5d6ffnetwork_name = kin.earthTa5d6ff" Tff7b72in Te6edf3encryptedTb4b4b4[Ta5d6ff"Ta5d6ffconfig_entryTa5d6ff"Tb4b4b4]

Te6edf3plain Tff7b72= Tffa657nextTb4b4b4(Te6edf3i Tff7b72for Te6edf3i Tff7b72in Te6edf3ifaces Tff7b72if Te6edf3iTb4b4b4[Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffopen-nodeTa5d6ff"Tb4b4b4)
Tff7b72assert Te6edf3plainTb4b4b4[Ta5d6ff"Ta5d6ffnetwork_nameTa5d6ff"Tb4b4b4] Tff7b72is Tff7b72None
Tff7b72assert Te6edf3plainTb4b4b4[Ta5d6ff"Ta5d6ffpassphraseTa5d6ff"Tb4b4b4] Tff7b72is Tff7b72None
Tff7b72assert Te6edf3plainTb4b4b4[Ta5d6ff"Ta5d6ffpublish_ifacTa5d6ff"Tb4b4b4] Tff7b72is Tff7b72False


Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffasyncio
Tff7b72async Tff7b72def Td2a8fftest_discovered_interfaces_filter_works_with_ifac_network_nameTb4b4b4(Te6edf3temp_dirTb4b4b4)Tb4b4b4:
T8b949e"""Whitelist/blacklist patterns can match an announce by its network_name."""
Te6edf3config Tff7b72= Te6edf3ConfigDictTb4b4b4(
Tb4b4b4{
Ta5d6ff"Ta5d6ffreticulumTa5d6ff"Tb4b4b4: Tb4b4b4{
Ta5d6ff"Ta5d6ffinterface_discovery_whitelistTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffkin.earthTa5d6ff"Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Ta5d6ff"Ta5d6ffinterfacesTa5d6ff"Tb4b4b4: Tb4b4b4{Tb4b4b4}Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4)

Tff7b72with Tb4b4b4(
Te6edf3patchTb4b4b4(Ta5d6ff"Ta5d6ffmeshchatx.meshchat.generate_ssl_certificateTa5d6ff"Tb4b4b4)Tb4b4b4,
Te6edf3patchTb4b4b4(Ta5d6ff"Ta5d6ffRNS.ReticulumTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3mock_rnsTb4b4b4,
Te6edf3patchTb4b4b4(Ta5d6ff"Ta5d6ffRNS.TransportTa5d6ff"Tb4b4b4)Tb4b4b4,
Te6edf3patchTb4b4b4(Ta5d6ff"Ta5d6ffLXMF.LXMRouterTa5d6ff"Tb4b4b4)Tb4b4b4,
Te6edf3patchTb4b4b4(Ta5d6ff"Ta5d6ffmeshchatx.meshchat.InterfaceDiscoveryTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3mock_discovery_clsTb4b4b4,
Tb4b4b4)Tb4b4b4:
Te6edf3mock_reticulum Tff7b72= Te6edf3mock_rnsTff7b72.Td2a8ffreturn_value
Te6edf3mock_reticulumTff7b72.Td2a8ffconfig Tff7b72= Te6edf3config
Te6edf3mock_reticulumTff7b72.Td2a8ffconfigpath Tff7b72= Ta5d6ff"Ta5d6ff/tmp/mock_configTa5d6ff"
Te6edf3mock_reticulumTff7b72.Td2a8ffis_connected_to_shared_instance Tff7b72= Tff7b72False
Te6edf3mock_reticulumTff7b72.Td2a8fftransport_enabledTff7b72.Td2a8ffreturn_value Tff7b72= Tff7b72True
Te6edf3mock_reticulumTff7b72.Td2a8ffget_interface_statsTff7b72.Td2a8ffreturn_value Tff7b72= Tb4b4b4{Ta5d6ff"Ta5d6ffinterfacesTa5d6ff"Tb4b4b4: Tb4b4b4[Tb4b4b4]Tb4b4b4}

Te6edf3mock_discovery_clsTff7b72.Td2a8ffreturn_valueTff7b72.Td2a8fflist_discovered_interfacesTff7b72.Td2a8ffreturn_value Tff7b72= Tb4b4b4[
Tb4b4b4{
Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffmatchingTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6fftypeTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffBackboneInterfaceTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffreachable_onTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ff10.0.0.1Ta5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffportTa5d6ff"Tb4b4b4: T79c0ff4242Tb4b4b4,
Ta5d6ff"Ta5d6ffifac_netnameTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffkin.earthTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffifac_netkeyTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffsecretTa5d6ff"Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4{
Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffnon-matchingTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6fftypeTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffBackboneInterfaceTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffreachable_onTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ff10.0.0.2Ta5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffportTa5d6ff"Tb4b4b4: T79c0ff4242Tb4b4b4,
Ta5d6ff"Ta5d6ffifac_netnameTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffother.netTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffifac_netkeyTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffotherTa5d6ff"Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4]

Te6edf3app_instance Tff7b72= Te6edf3ReticulumMeshChatTb4b4b4(
Te6edf3identityTff7b72=Te6edf3build_identityTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3storage_dirTff7b72=Te6edf3temp_dirTb4b4b4,
Te6edf3reticulum_config_dirTff7b72=Te6edf3temp_dirTb4b4b4,
Tb4b4b4)

Te6edf3handler Tff7b72= Tff7b72await Te6edf3find_route_handlerTb4b4b4(
Te6edf3app_instanceTb4b4b4,
Ta5d6ff"Ta5d6ff/api/v1/reticulum/discovered-interfacesTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ffGETTa5d6ff"Tb4b4b4,
Tb4b4b4)
Tff7b72assert Te6edf3handler

Te6edf3response Tff7b72= Tff7b72await Te6edf3handlerTb4b4b4(Te6edf3MagicMockTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3data Tff7b72= Te6edf3jsonTff7b72.Td2a8ffloadsTb4b4b4(Te6edf3responseTff7b72.Td2a8ffbodyTb4b4b4)
Tff7b72assert Tffa657lenTb4b4b4(Te6edf3dataTb4b4b4[Ta5d6ff"Ta5d6ffinterfacesTa5d6ff"Tb4b4b4]Tb4b4b4) Tff7b72== T79c0ff2

Te6edf3matching Tff7b72= Tffa657nextTb4b4b4(Te6edf3i Tff7b72for Te6edf3i Tff7b72in Te6edf3dataTb4b4b4[Ta5d6ff"Ta5d6ffinterfacesTa5d6ff"Tb4b4b4] Tff7b72if Te6edf3iTb4b4b4[Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffmatchingTa5d6ff"Tb4b4b4)
Te6edf3non_matching Tff7b72= Tffa657nextTb4b4b4(
Te6edf3i Tff7b72for Te6edf3i Tff7b72in Te6edf3dataTb4b4b4[Ta5d6ff"Ta5d6ffinterfacesTa5d6ff"Tb4b4b4] Tff7b72if Te6edf3iTb4b4b4[Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffnon-matchingTa5d6ff"
Tb4b4b4)
Tff7b72assert Te6edf3matchingTb4b4b4[Ta5d6ff"Ta5d6ffis_allowedTa5d6ff"Tb4b4b4] Tff7b72is Tff7b72True
Tff7b72assert Te6edf3non_matchingTb4b4b4[Ta5d6ff"Ta5d6ffis_allowedTa5d6ff"Tb4b4b4] Tff7b72is Tff7b72False
Tff7b72assert Te6edf3matchingTb4b4b4[Ta5d6ff"Ta5d6ffnetwork_nameTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffkin.earthTa5d6ff"
Tff7b72assert Te6edf3matchingTb4b4b4[Ta5d6ff"Ta5d6ffpassphraseTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffsecretTa5d6ff"


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────